﻿/**
 *
 *	A class which implements a button functionality.
 *	In addition to the states operable by a ClickableMovie (DynamicState.UP and DynamicState.DOWN) it uses also DynamicState.OVER and DynamicState.OUT constants.
 *	Also there's a toggleState property which is either DynamicState.UP and DynamicState.DOWN.
 *	
 *	@author	Valentyn Derkach
 *
 *	2008.06.15
 *	Changes:
 *	 -	method release has been changed - doRollOver call there has been added
 *
 */

package com.bizmlib.ui.display
{
	import flash.display.DisplayObject;
	import flash.display.InteractiveObject;
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	
	public class DynamicButton extends ClickableMovie
	{
		protected var rollOverState:String;
		protected var toggleState:String = DynamicState.UP;
		protected var doInitialRollOverStateCheckUp:Boolean = false;
		protected var doInitialMouseEnabledCheckUp:Boolean = true;
		protected var ignoreMouseEnabledForRollOver:Boolean = true;
		protected var ignoreMouseEnabledForRollOut:Boolean = true;
		
		private var __toggle:Boolean = false;
		
		
		public function DynamicButton()
		{
			super();
		}
		
		
		public function set toggle(value:Boolean):void
		{
			__toggle = value;
			updateToggle();
		}
		public function get toggle():Boolean
		{
			return __toggle;
		}
		
		
		override public function release():void
		{
			//trace(this + ".release(" + arguments + ")");
			
			if(toggleState==DynamicState.UP)
			{
				return;
			}
			
			super.release();
		}
		override public function clean():void
		{
			super.clean();
		}
		
		
		override protected function afterMouseEnabledUpdate():Boolean
		{
			//trace(this + ".afterMouseEnabledUpdate(" + arguments + ")");
			
			if(super.afterMouseEnabledUpdate())
			{
				return true;
			}
			
			if(!mouseEnabled && state==DynamicState.OVER)
			{
				rollOut();
				return true;
			}
			
			return false;
		}
		
		
		override protected function init():void
		{
			//trace(this + ".init(" + arguments + ")");
			
			this.addEventListener(MouseEvent.ROLL_OVER, rollOver);
			this.addEventListener(MouseEvent.ROLL_OUT, rollOut);
			this.addEventListener(Event.ADDED_TO_STAGE, addedToStageFirstTime);
			this.addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
			
			rollOverState = DynamicState.OUT;
			
			super.init();
		}
		protected function addedToStageFirstTime(event:Event):void
		{
			//trace(this + ".addedToStageFirstTime(" + arguments + ")");
			
			this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageFirstTime);
			
			if((!mouseEnabled) || (!doInitialRollOverStateCheckUp))
			{
				doRollOut();
				return;
			}
			/**
			else if(!doInitialRollOverStateCheckUp)
			{
				return;
			}
			/**/
			
			var mouseEnabledSummary:Boolean = mouseEnabled && mouseChildren;
			var currentItem:DisplayObject = this as DisplayObject;
			//trace(currentItem);
			while(mouseEnabledSummary && currentItem.parent && currentItem.parent!=currentItem)
			{
				currentItem = currentItem.parent as DisplayObject;
				//trace(currentItem);
				
				if(currentItem)
				{
					var currentMouseEnabled:Boolean = (currentItem is InteractiveObject) ? (currentItem as InteractiveObject).mouseEnabled : true;
					var currentMouseChildren:Boolean = (currentItem is DisplayObjectContainer) ? (currentItem as DisplayObjectContainer).mouseChildren : true;
					mouseEnabledSummary &&= currentMouseEnabled && currentMouseChildren;
				}
			}
			//trace("mouseEnabledSummary=" + mouseEnabledSummary);
			
			if(mouseEnabledSummary && this.hitTestPoint(stage.mouseX, stage.mouseY))
			{
				rollOver();
			}
			else
			{
				rollOut();
			}
		}
		
		
		protected function rollOver(event:MouseEvent = null):void
		{
			//trace(this + ".rollOver(" + arguments + ")");
			//trace("state=" + state + "\trollOverState=" + rollOverState + "\ttoggleState=" + toggleState);
			//trace(event ? event.target : undefined);
			//trace(mouseEnabled);
			
			if(!ignoreMouseEnabledForRollOver && !mouseEnabled)
			{
				return;
			}
			
			rollOverState = DynamicState.OVER;
			
			if(toggleState==DynamicState.DOWN)
			{
				return;
			}
			
			if(state!=DynamicState.DOWN && mouseEnabled)
			{
				__state = DynamicState.OVER;
				doRollOver();
			}
		}
		protected function rollOut(event:MouseEvent = null):void
		{
			//trace(this + ".rollOut(" + arguments + ")");
			//trace("state=" + state + "\trollOverState=" + rollOverState + "\ttoggleState=" + toggleState);
			//trace(event ? event.target : undefined);
			//trace(mouseEnabled);
			
			if(!ignoreMouseEnabledForRollOut && !mouseEnabled)
			{
				return;
			}
			
			rollOverState = DynamicState.OUT;
			
			if(toggleState==DynamicState.DOWN)
			{
				return;
			}
			
			if(state!=DynamicState.DOWN && mouseEnabled)
			{
				__state = DynamicState.OUT;
				doRollOut();
			}
		}
		override protected function releaseImplementation(doStateChange:Boolean = true, invokeCustomImplementation:Boolean = true):void
		{
			//trace(this + ".releaseImplementation(" + arguments + ")");
			
			__state = rollOverState;
			
			if(toggle)
			{
				toggleState = (toggleState == DynamicState.UP) ? DynamicState.DOWN : DynamicState.UP;
				
				if(toggleState==DynamicState.DOWN)
				{
					invokeCustomImplementation = false;
					__state = DynamicState.DOWN;
				}
				else
				{
				}
			}
			
			super.releaseImplementation(false, /**true/**!toggle/**/invokeCustomImplementation);
			
			//trace("toggleState=" + toggleState);
			
			if(toggleState==DynamicState.DOWN)
			{
			}
			else if(state==DynamicState.OUT)
			{
				doRollOut();
			}
			else
			{
				doRollOver();
			}
		}
		
		
		protected function doRollOver():void
		{
			//trace(this + ".doRollOver(" + arguments + ")");
		}
		protected function doRollOut():void
		{
			//trace(this + ".doRollOut(" + arguments + ")");
		}
		
		
		protected function updateToggle():void
		{
			
		}
		
		
		private function removedFromStage(event:Event):void
		{
			this.removeEventListener(MouseEvent.ROLL_OVER, rollOver);
			this.removeEventListener(MouseEvent.ROLL_OUT, rollOut);
			this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageFirstTime);
			this.removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
		}
		
		override public function toString():String
		{
			return "[DynamicButton	name:" + name + "	state:" + state + "	rollOverState:" + rollOverState + "	toggleState:" + toggleState + "]";
		}
	}
}